// 文件路径: dbms/execution/execution/CreateTableExecutor.java
package com.dbms.execution.execution;

import com.dbms.catalog.Catalog;
import com.dbms.common.Schema;
import com.dbms.common.Tuple;
import com.dbms.execution.plan.PlanNode;
import com.dbms.parser.ast.ForeignKeyNode;

import java.io.IOException;
import java.util.List;

/**
 * 【已修改】
 * CreateTableExecutor (创建表执行器) 负责执行创建表的计划。
 * 这个版本的执行器能够处理外键定义，
 * 在创建表时会将外键信息一并传递给 Catalog（目录管理器）进行注册。
 */
public class CreateTableExecutor implements Executor {

    /**
     * 目录管理器实例，用于访问数据库的元数据和执行表创建操作。
     */
    private final Catalog catalog;

    /**
     * 要创建的表的名称。
     */
    private final String tableName;

    /**
     * 要创建的表的模式（Schema），定义了表的列名和类型。
     */
    private final Schema schema;

    /**
     * 表的外键约束列表。
     */
    private final List<ForeignKeyNode> foreignKeys;

    /**
     * 一个标志，用于确保 `next()` 方法中的创建逻辑只执行一次。
     */
    private boolean hasExecuted = false;

    /**
     * 构造函数，用于初始化一个包含外键定义的创建表执行器。
     * @param catalog 目录管理器
     * @param tableName 表名
     * @param schema 表的模式
     * @param foreignKeys 外键列表
     */
    public CreateTableExecutor(Catalog catalog, String tableName, Schema schema, List<ForeignKeyNode> foreignKeys) {
        this.catalog = catalog;
        this.tableName = tableName;
        this.schema = schema;
        this.foreignKeys = foreignKeys;
    }

    /**
     * 构造函数，用于初始化一个不包含外键定义的创建表执行器。
     * @param catalog 目录管理器
     * @param tableName 表名
     * @param schema 表的模式
     */
    public CreateTableExecutor(Catalog catalog, String tableName, Schema schema) {
        // 调用另一个构造函数，并传入一个空的外键列表
        this(catalog, tableName, schema, new java.util.ArrayList<>());
    }

    /**
     * 打开执行器，准备执行。
     * 在这里，我们将执行状态重置为 false。
     */
    @Override
    public void open() {
        hasExecuted = false;
    }

    /**
     * 执行创建表的逻辑。
     * 这个方法只会在第一次调用时执行实际的创建操作。后续调用将返回 null。
     * DDL (数据定义语言) 操作通常不返回元组。
     * @return 总是返回 null。
     */
    @Override
    public Tuple next() {
        // 如果已经执行过，直接返回 null，防止重复创建
        if (hasExecuted) {
            return null;
        }

        try {
            // 调用 catalog 的 createTable 方法，将表名、模式和外键信息一并传入
            catalog.createTable(tableName, schema, foreignKeys);
            // 标记为已执行
            hasExecuted = true;
        } catch (IOException e) {
            // 如果创建过程中发生 IO 异常，打印堆栈跟踪并抛出运行时异常
            e.printStackTrace();
            throw new RuntimeException("Failed to create table", e);
        }

        // DDL 操作不产生任何元组，所以返回 null
        return null;
    }

    /**
     * 关闭执行器。
     * 对于创建表操作，通常不需要进行特殊的清理工作。
     */
    @Override
    public void close() {
        // 无需特殊操作
    }

    /**
     * 获取输出模式。
     * 创建表操作不产生任何输出元组，因此没有输出模式。
     * @return 总是返回 null。
     */
    @Override
    public Schema getSchema() {
        return null;
    }



    /**
     * 获取关联的计划节点。
     * @return 总是返回 null。
     */
    @Override
    public PlanNode getPlanNode() {
        return null;
    }
}